#pragma once
#include <QObject>
#include <QTcpSocket>
#include "Secure.hpp"
#include "Protocol.hpp"


// 具体TCP实现
class TcpService : public QObject
{
    Q_OBJECT
public:
    explicit TcpService(QObject *parent = nullptr)
            : QObject(parent)
        {
            socket = new QTcpSocket(this);

            connect(socket, &QTcpSocket::connected, this, &TcpService::onConnected);
            connect(socket, &QTcpSocket::disconnected, this, &TcpService::onDisconnected);
            connect(socket, &QTcpSocket::readyRead, this, &TcpService::onReadyRead);
            connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
                    this, &TcpService::onError);
        }

        ~TcpService() override
        {
            disconnectFromServer();
            socket->close();
        }

        bool connectToServer(const QString &host, quint16 port)
        {
            if (socket->state() == QAbstractSocket::ConnectedState)
                return true;

            socket->connectToHost(host, port);
            return socket->waitForConnected(3000);
        }

        void disconnectFromServer()
        {
            if (socket->state() != QAbstractSocket::UnconnectedState)
            {
                socket->disconnectFromHost();
                if (socket->state() == QAbstractSocket::ConnectedState)
                {
                    if (!socket->waitForDisconnected())
                    {
                        qWarning() << "Wait for disconnected timeout, force closing socket";
                    }
                }
            }
        }

        bool isConnected() const
        {
            return socket->state() == QAbstractSocket::ConnectedState;
        }

        QString errorString() const
        {
            return socket->errorString();
        }

        bool sendData(const ProtocolPtr& req)
        {
            if (!isConnected() || !req) return false;

            // 序列化协议数据
            QString jsonData = req->serialize();
            QByteArray plainData = jsonData.toUtf8();

            // 添加5字节长度头
            QByteArray lengthHeader = Secure::encodeLength(plainData.size());
            QByteArray packet = lengthHeader + plainData;

            // 加密整个报文（包括长度头）
            QByteArray encryptedPacket = Secure::encrypt(packet);
            qDebug() << "报文长度: " << plainData.length();
            qDebug() << encryptedPacket;
            // 发送加密后的报文
            qint64 bytesWritten = socket->write(encryptedPacket);
            return bytesWritten == encryptedPacket.size();
        }

    signals:
        void connected();
        void disconnected();
        void errorOccurred(const QString &error);
        void messageReceived(const ProtocolPtr &protocol);

    private slots:
        void onConnected()
        {
            qDebug() << "TCP Connected";
            emit connected();
        }

        void onDisconnected()
        {
            qDebug() << "TCP Disconnected";
            emit TcpService::disconnected();
        }

        void onReadyRead()
        {
            receiveBuffer.append(socket->readAll());

            // 处理所有完整的消息
            while (processIncomingData()) {}
        }

        void onError(QAbstractSocket::SocketError socketError)
        {
            (void)socketError;
            qDebug() << "TCP Error:" << socket->errorString();
            emit errorOccurred(socket->errorString());
        }

    private:
        // 处理接收缓冲区中的数据
        bool processIncomingData()
        {

            // 至少需要5字节长度头（加密状态）
            if (receiveBuffer.size() < 5) return false;

            // 尝试解密前5字节（长度头）
            QByteArray decryptedHeader = Secure::decrypt(receiveBuffer.left(5));

            // 解码长度
            quint64 messageLength = Secure::decodeLength(decryptedHeader);

            // 计算完整消息所需的总长度
            quint64 totalMessageLength = 5 + messageLength;

            // 检查是否收到完整的消息
            if ((quint64)receiveBuffer.size() < totalMessageLength) return false;

            // 提取完整消息
            QByteArray encryptedMessage = receiveBuffer.left(totalMessageLength);
            // 移除已处理的数据
            receiveBuffer = receiveBuffer.mid(totalMessageLength);

            // 解密整个消息
            QByteArray decryptedMessage = Secure::decrypt(encryptedMessage);

            // 提取实际数据（跳过5字节长度头）
            QByteArray jsonData = decryptedMessage.mid(5);
            QString jsonMessage = QString::fromUtf8(jsonData);

//            qDebug() << "解析协议开始";
            // 解析协议
            ProtocolPtr protocol = ProtocolFactory::createProtocolFromJson(jsonMessage);
//            qDebug() << "解析协议完成";

            if (protocol)
            {
                emit messageReceived(protocol);
            } else
            {
                qDebug() << "Invalid protocol format:" << jsonMessage;
            }

            return true;
        }
private:
    QTcpSocket* socket;
    QByteArray receiveBuffer;
};

